---
layout: default
---
Interpreter
---
You can try out the language by opening the interpreter and making _queries_ to the language.

```
$ cosmos -i
> x=1
| x = 1
> x=1 or 2=x
| x = 1
| x = 2
```

Writing a file
---

Make a file `hello.co` with the content,

`print('hello world')`

The file can be loaded with the `-l` flag.

```
$ cosmos -l hello
'hello world'`
```

Relations
----

Instead of functions, Cosmos has relations.

They're made using the `rel` keyword.

```javascript
//note that the there is no 'return' in the definition
//instead, the parameter y is explicit
//this is typically the 'output' parameter
rel double(x, y)
    y = x*2

double(4,x) //x is 8
```

Whereas functions have one output, relations may have zero, one or more outputs. You can check this by making queries at the interpreter.

```$
cosmos -i
> x=1 or x=2 //this query has two answers (outputs)
| x = 1
| x = 2
```

If the system picks one answer and it turns out to be invalid, the system will backtrack and pick the other.

```javascript
rel p(x)
    x=1 or x=2
    
rel main()
	p(x)
	x!=1
	io.writeln(x) //2
```

Relations may adopt function syntax. This lets relations be nested.

```javascript
double(4,x) //logic syntax
x=double(4) //function syntax
print(double(3)) //this will print 6
```

Logic-wise, `double(4,x)` is read as a statement: "the double of 4 is x".

`double(4)` reads as "the double of 4".

First-class relation
---

Relations are first-class values. It's possible to define a relation within another.
```
rel p(x)
    rel temp(x)
        x = 2
    temp(x)
    
p(x) //x is 2
```
Alternatively:
```
rel p(x)
    temp = rel(x)
        x = 2
    temp(x)
```

Functors
----

Functors are composite data.
```
functor(F, Functor) //declares an object for creating functors
x = F(1, 2) //x is assigned to a functor F composed by the values 1 and 2
x = F(1, a) //uses pattern matching to match F(1, 2) against F(1, a)
print(a) //2
```
The special relation _functor_ is used to declare F as an object for making functors.

Lists are syntax sugar for the functor Cons. Here are two ways to define a list:

```
l = [1, 2]
l = Cons(1, Cons(2, Cons))
```

Relations such as _first_, _map_ and _filter_ can be used to manipulate lists.

```
l = [1,2,3]
list.first(l, head) //head is 1
list.rest(l, tail) //tail is [2, 3]
list.map(l, math.inc, l2) //l2 is [2, 3, 4]
list.map(l3, math.inc, l) //l3 is [0, 1, 2]
list.filter(l, rel(x) x!=3;, l4) //l4 is [1, 2]
```

Immutability
----

Variables are immutable. Instead of modifying a value we create a new one.

```
l2 = list.push(l, 55) //instead of modifying l, we create a new variable l2
io.writeln(l)  //[1, 2, 3]
io.writeln(l2) //[1, 2, 3, 55]
```

Cosmos adopts many principles and features that are common in functional programming languages (although the principles apply to *relations* rather than *functions*).

Types
----

Cosmos manages a balance between strictness and non-strictness. Writing the type of a variable is (almost always) optional.

```javascript
    Integer n = 7
    Real x = 5.2
    String s = 'abc'
    z = 5 //z is implied to be an Integer
    Functor l = [1, 2, 3]
    functor(F, Functor)
    Functor f = F('apple', 5)
```

The type system supports *composite types*.
```
    Functor String Number f2 = F('apple', 2)
```
*Functor String Number* is a composite type that accepts any functor whose first element is a string and second is a number.
```
    Relation Any Any p = double
```
Relations get composite types. *Relation Any Any* is a type that accepts any relation with exactly two arguments.

Tables
----

Tables (also known as maps, dictionaries, etc.) are structures that map keys to values.

```javascript
Table t = {x=1 and y=2}
table.set(t, 'a', 1, t2)

print(t) //{'x': 1, 'y': 2}
print(t2) //{'x': 1, 'y': 2, 'a': 1}
```

Making a module
---

Cosmos files are typically given the .co extension.

```js
//x.co
rel p(x)
    x=2
	
t = {
	'p' = p
}
export(t)
```
As we have mentioned, Cosmos is in part inspired by imperative scripting languages--specifically, prototypal ones. 

The principle is thus the same. The relation `p` is inserted into a table, which is then exported.

This could've been written as,

```js
//x.co
t = {
	rel p(x)
		x=2
}
export(t)
```

We then use the special relation `require`,

```
require('x', x)
x.p(2)
print(x) //2
```

Whitespace
----

The language is whitespace sensitive.
```js
rel p(x)
    x!=1
    x<5
```
This could be a single line.
```js
rel p(x) x!=1 and x<5;
```
It's possible to drop the whitespace semantics by writing the unnecessary characters, although this is not generally advisable.

Note that statements are separated by _ands_ (semicolons are only used to end the indendation).

Booleans
----

There is no boolean type. Instead, relations themselves are "booleans".

Using cases
---

`and/or` is a huge part of the language. Hence, there are many operators that are shorthand for `and/or`. One of them is `case` (alias: `cond`).


```js
case
	s = 'a'
	x = 1
case
	s = 'b'
```

This is sugar for,

```
(s = 'a' and x=1) or (s = 'b')
```

You could even use `when`, which is simply a different form of _case_.

This could be written as,

```
when(s = 'a')
	x = 1
else
	x = 'b'
```

Note that the condition is kind of redundant here.

That's why the actual if-statement and favoured conditional of the language is as follows.

Conditional
---

```js
if(s = 'a')
	x = 0
else
	x = 2
```

A conditional is equivalent to,

```lua
(s = 'a' and x = 0) or (not s = 'a' and x = 2)
```

Or,

```lua
(s = 'a' and x = 0) or (s != 'a' and x = 2)
```
 
Negation is complicated
---

Let's see an example of a more complex condition.

```js
rel main(x)
	if(p(x))
		x=1
	else
		x=2
```

The condition this time is p(x). How do we negate an arbitrary relation like p(x)? All the while keeping the code logically pure?

The operators `not/if/while` are more complicated than they seem on the surface. Still, the result should be as expected. In order to ensure it's sound, _p(x)_ may be called twice or delayed. In the worst case, `x=1` might be executed before `p(x)`.

This can always be turned off by making it a function,

```
fun main(x)
	if(p(x))
		x=1
	else
		x=2
```

When encased in a function, _if_ behaves as an imperative conditional. It will not do any _backtracking_ or _non-determinism_.

Impure operators
---

As a principle, code that uses `rel` should behave like a pure relation and code using `fun` like a regular function as in functional or procedural programming.

This is more-or-less an improvement over Prolog's _negation-by-failure_. By comparison, standard-compliant Prolog deprecates usage of the `not` keyword at all and many logical operators are by default not pure. This makes it more-or-less difficult to simply try out logic programming at all.

We still provide a few non-pure operators like _once_.

```
//this will only select the first answer given by p(x)
once p(x)
```

Pseudo-imperative Programming
--

As Cosmos was made to explore declarative programming, where data is immutable, it's not truly imperative. However, procedural-style programming is possible using the pseudo-imperative operator, `!`. (Like functions, this feature is in-development.)

```
!x=x+1
```

This is akin to writing,

```
x2=x1+1
```

The operator indicates that the alias _x_ is changed to a different value in the current relation.

This allows us to make _for_ and _while_ statements!

```
for(x=1;x<=3;!x=x+1;)
	print(x) //1, 2, 3
```
